package com.infocollect.project.wx.controller;

import com.alibaba.fastjson.JSONObject;
import com.infocollect.common.constant.Constants;
import com.infocollect.common.exception.CustomException;
import com.infocollect.common.utils.BankInfoUtils;
import com.infocollect.common.utils.ServletUtils;
import com.infocollect.common.utils.sign.AES;
import com.infocollect.framework.redis.RedisCache;
import com.infocollect.framework.web.controller.BaseController;
import com.infocollect.framework.web.domain.AjaxResult;
import com.infocollect.project.grant.domain.*;
import com.infocollect.project.grant.service.*;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

@AllArgsConstructor
@RestController
@RequestMapping("/wx")
public class GrantExaminerController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(GrantExaminerController.class);
    private static final String PHONE_CODE = "PHONE_CODE";
    @Autowired
    IGrExaminerService grExaminerService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private IGrGrantService grantService;
    @Autowired
    private IGrExaminerService examinerService;
    @Autowired
    private IGrExaminerGrantService examinerGrantService;
    @Autowired
    private IGrExamPointService examPointService;
    @Autowired
    private IGrExaminerBankcardService bankcardService;
    @Autowired
    private IGrFamiliesExampointService grFamiliesExampointService;
    @Autowired
    private IGrFamiliesService familiesService;
    @Autowired
    private IGrCompanyService companyService;
    @Autowired
    private IGrGranttypeService granttypeService;
    @Autowired
    private IGrCompanyPlanService grCompanyPlanService;

    /**
     * 用户登陆页面根据证件号码获取姓名和手机号码
     * @param grExaminerGrantDto
     * @return
     */
    @ResponseBody
    @PostMapping("getUserNameAndPhoneForIdcard")
    public AjaxResult getUserNameAndPhoneForIdcard(@RequestBody GrExaminerGrantDto grExaminerGrantDto) {
        String idCard = grExaminerGrantDto.getIdcard();
        if(idCard.isEmpty()){
            return AjaxResult.success(grExaminerGrantDto);
        }
        GrExaminer grExaminer = new GrExaminer();
        grExaminer.setIdcard(idCard);

        List<GrExaminer> examinerList =  grExaminerService.selectGrExaminerList(grExaminer);
        if(examinerList.size()>0){
            grExaminer = examinerList.get(0);
            grExaminerGrantDto.setName(grExaminer.getName());
            grExaminerGrantDto.setPhone(grExaminer.getPhone());
        }

        return AjaxResult.success(grExaminerGrantDto);
    }

    /**
     * 获取用户项目报名信息
     * @param grExaminerGrantDto
     * @return
     */
    @ResponseBody
    @PostMapping("getUserInfoForIdcardandGrantid")
    public AjaxResult getUserInfoForIdcardandGrantid(@RequestBody GrExaminerGrantDto grExaminerGrantDto) {
        GrExaminer examiner = new GrExaminer();
        examiner.setIdcard(grExaminerGrantDto.getIdcard());
        List<GrExaminer> examinerList = examinerService.selectGrExaminerList(examiner);
        if(examinerList.size()<=0){
            return AjaxResult.success(grExaminerGrantDto);
        }
        examiner = examinerList.get(0);
        GrExaminerGrant examinerGrant = new GrExaminerGrant();
        examinerGrant.setGrantId(grExaminerGrantDto.getGrantId());
        examinerGrant.setExaminerId(examiner.getId());
        List<GrExaminerGrantDto> grExaminerGrantDtoList = examinerGrantService.selectGrExaminerGrantDtoList(grExaminerGrantDto);
        if(grExaminerGrantDtoList.size()<=0){
            grExaminerGrantDto.setExaminerId(examiner.getId());
            grExaminerGrantDto.setName(examiner.getName());
            grExaminerGrantDto.setPhone(examiner.getPhone());
            grExaminerGrantDto.setSex(examiner.getSex());
            grExaminerGrantDto.setPhotoUrl(examiner.getPhotoUrl());
            grExaminerGrantDto.setTeachAge(examiner.getTeachAge());
            grExaminerGrantDto.setPost(examiner.getPost());
            grExaminerGrantDto.setTechnicalTitle(examiner.getTechnicalTitle());
            return AjaxResult.success(grExaminerGrantDto);
        }
        grExaminerGrantDto = grExaminerGrantDtoList.get(0);
        return AjaxResult.success(grExaminerGrantDto);
    }
    @ResponseBody
    @PostMapping("examinerLogin")
    public AjaxResult examinerLogin(@RequestBody ExaminerLoginDto examinerLoginDto){
//        String smsCode = examinerLoginDto.getSmsCode();
        String wechatId = examinerLoginDto.getWechatId();
//        Long grantId = examinerLoginDto.getGrantId();
        if(StringUtils.isNotEmpty(wechatId)){
            GrExaminer grExaminer = new GrExaminer();
            grExaminer.setWechatId(wechatId);
            List<GrExaminer> examinerList =  grExaminerService.selectGrExaminerList(grExaminer);
            if(examinerList.size()>0){
                grExaminer = examinerList.get(0);
                examinerLoginDto.setName(grExaminer.getName());
                examinerLoginDto.setSmsCode("888888");
                examinerLoginDto.setPhone(grExaminer.getPhone());
                examinerLoginDto.setIdcard(grExaminer.getIdcard());
            }
        }
        String name = examinerLoginDto.getName();
        String phone = examinerLoginDto.getPhone();
        String idcard = examinerLoginDto.getIdcard();
        AjaxResult checkResult= checkExaminerLoginInfo(examinerLoginDto);
        if((int)checkResult.get("code")!=200){
            return checkResult;
        }
//        GrGrant grant = grantService.selectGrGrantById(grantId);
        GrExaminer grExaminer = new GrExaminer();
        grExaminer.setIdcard(idcard);
        List<GrExaminer> examinerList =  grExaminerService.selectGrExaminerList(grExaminer);
        if(examinerList.size()>0){
            grExaminer = examinerList.get(0);
            if(StringUtils.isNotEmpty(wechatId)) {
                grExaminer.setWechatId(wechatId);
                grExaminerService.updateGrExaminer(grExaminer);
            }
        }else{
            grExaminer = new GrExaminer();
            grExaminer.setIdcard(idcard);
            grExaminer.setPhone(phone);
            grExaminer.setWechatId(wechatId);
            grExaminer.setName(name);
            grExaminerService.insertGrExaminer(grExaminer);
        }

        Long grantId= examinerLoginDto.getGrantId();
        GrGrant grant= grantService.selectGrGrantById(grantId);
        GrGranttype granttype = granttypeService.selectGrGranttypeById(grant.getGranttypeId());
        grExaminer.setGrantType(granttype.getInputType());
        return AjaxResult.success(grExaminer);
    }

    /**
     * 保存人员报名基本信息
     * @param examiner
     * @return
     */
    @ResponseBody
    @PostMapping("updGrExaminer")
    public AjaxResult updGrExaminer(@RequestBody GrExaminer examiner){
        Integer id = null;
        GrExaminer grExaminerSearch = new GrExaminer();
        grExaminerSearch.setIdcard(examiner.getIdcard());
        List<GrExaminer> examinerList = examinerService.selectGrExaminerList(grExaminerSearch);
        if(examinerList.size()>0){
            examiner.setId(examinerList.get(0).getId());
        }else{
            AjaxResult.error("错误的人员信息");
        }
        examiner.setIdcard(examiner.getIdcard().toUpperCase());
        id = examinerService.updateGrExaminer(examiner);
        if(id==null){
            AjaxResult.error("保存错误");
        }
        return AjaxResult.success();
    }

    /**
     * 保存人员项目报名信息
     * @param examinerGrant
     * @return
     */
    @ResponseBody
    @Transactional
    @PostMapping("updGrExaminerGrant")
    public AjaxResult updGrExaminerGrant(@RequestBody GrExaminerGrant examinerGrant){
        Integer id = null;
        GrExaminer examiner = examinerService.selectGrExaminerById(examinerGrant.getExaminerId());
        if(examiner==null){
            return AjaxResult.error("人员信息获取失败");
        }
        GrExamPoint examPoint = examPointService.selectGrExamPointById(examinerGrant.getExamPointId());
        if(examPoint==null){
            return AjaxResult.error("考点信息获取失败");
        }
        GrGrant grant = grantService.selectGrGrantById(examinerGrant.getGrantId());
        if(grant==null||"停止申报".equals(grant.getUpStatus())){
            return AjaxResult.error("报名已截止，不允许修改！");
        }
        AjaxResult checkBankResult = checkBlanInfo(examinerGrant,examPoint);
        //银行卡校验不通过，直接返回错误
        if((int)checkBankResult.get("code")!=200){return checkBankResult;}
        GrExaminerGrant examinerGrantSearch = new GrExaminerGrant();
        examinerGrantSearch.setGrantId(examinerGrant.getGrantId());
        examinerGrantSearch.setExaminerId(examinerGrant.getExaminerId());
        List<GrExaminerGrant> examinerGrantList =  examinerGrantService.selectGrExaminerGrantList(examinerGrantSearch);
        if(examinerGrantList.size()>0){
            examinerGrant.setId(examinerGrantList.get(0).getId());
        }
        //已经存在该用户了，就更新
        if (examinerGrant.getId() == null) {
            if(!checkSubjectPlanCount(examinerGrant)){
                return AjaxResult.error("报名人数已超过计划数，不允许提交！");
            }
            examinerGrantService.insertGrExaminerGrant(examinerGrant);
        }else{
            examinerGrantService.updateGrExaminerGrant(examinerGrant);
        }
        if("Y".equals(examinerGrant.getIsReplace())){
            //如果是替班人员，要把被替班的人信息给更新一下。
            Long relationGrexaminerId =  Long.valueOf(examinerGrant.getRelationGrexaminerId());
            GrExaminerGrant relationGrexaminer = examinerGrantService.selectGrExaminerGrantById(relationGrexaminerId);
            relationGrexaminer.setIsNeedReplace("Y");
            relationGrexaminer.setRelationGrexaminerId(String.valueOf(examinerGrant.getExaminerId()));
            GrExaminer grExaminer = examinerService.selectGrExaminerById(examinerGrant.getExaminerId());
            relationGrexaminer.setRelationGrexaminerName(grExaminer.getName());
            examinerGrantService.updateGrExaminerGrant(relationGrexaminer);
        }
        return AjaxResult.success();
    }
    private boolean checkSubjectPlanCount(GrExaminerGrant examinerGrant){
        if("Y".equals(examinerGrant.getIsReplace())){
            return true;
        }
        GrCompanyPlan grCompanyPlan = new GrCompanyPlan();
        grCompanyPlan.setCompanyId(examinerGrant.getCompanyId());
        grCompanyPlan.setGrantId(examinerGrant.getGrantId());
        grCompanyPlan.setSubjectCode(examinerGrant.getSubjectCode());
        List<GrCompanyPlan> list = grCompanyPlanService.selectGrCompanyPlanList(grCompanyPlan);
        if(list.size()==0){
            return true;
        }
        grCompanyPlan = list.get(0);
        if(grCompanyPlan.getPlanNum() > grCompanyPlan.getEnrollNum()){
            return true;
        }
        return false;
    }
    /**
     * 校验银行卡信息
     * @return
     */
    public AjaxResult checkBlanInfo(GrExaminerGrant examinerGrant, GrExamPoint examPoint){
        GrExaminer examiner = examinerService.selectGrExaminerById(examinerGrant.getExaminerId());
        if ("Y".equals(examPoint.getIsBank())) {
            GrExaminerBankcard examinerBankcard = new GrExaminerBankcard();
            examinerBankcard.setExaminerId(examinerGrant.getExaminerId());
            examinerBankcard.setBankCard(examinerGrant.getBlankCark());
            examinerBankcard.setVerifyFlag(1);
            List<GrExaminerBankcard> bankcardList = bankcardService.selectGrExaminerBankcardList(examinerBankcard);
            //有数据了，直接用表里的数据做校验
            if(bankcardList.size()>0){
                examinerBankcard = bankcardList.get(0);
                String bankName = examinerBankcard.getBankName();
                String bankType = examinerBankcard.getCardType();
                examinerGrant.setBlankName(bankName);
                if (!org.apache.commons.lang.StringUtils.isEmpty(examPoint.getBankNameLimit())
                        && examPoint.getBankNameLimit().indexOf(bankName) < 0) {
                    return AjaxResult.error("该卡号所在银行不支持，请更换该考点所支持的卡号");
                }
                if (!org.apache.commons.lang.StringUtils.isEmpty(examPoint.getBankTypeLimit())) {
                    String[] bankTypes = examPoint.getBankTypeLimit().split(",");
                    for (int ni = 0; ni < bankTypes.length; ni++) {
                        if (bankTypes[ni].indexOf(bankName) >= 0 && !bankTypes[ni].contains(bankName + "(" + bankType + ")")) {
                            return AjaxResult.error("该卡号类型不支持，当前支持卡类型:" + examPoint.getBankTypeLimit());
                        }
                    }
                }
            }else
            {
                String redisKey = "BANK_" + examinerGrant.getBlankCark() + "-" + examiner.getName()+"-"+ examiner.getIdcard();
                //接口校验银行卡
                String result = redisCache.getCacheObject(redisKey);
                if (redisCache.getCacheObject("BANK_" + examinerGrant.getBlankCark() + "-" + examiner.getIdcard()) == null) {
                    result = BankInfoUtils.bankVerifyNew(examiner.getName(), examinerGrant.getBlankCark(), examiner.getIdcard(),
                            "01");
                    if (result != null && !org.apache.commons.lang.StringUtils.isEmpty(result)) {
                        redisCache.setCacheObject(redisKey, result,2, TimeUnit.HOURS);
                    }else {
                        result = (String) redisCache.getCacheObject(redisKey);
                    }
                }
                if (org.apache.commons.lang.StringUtils.isEmpty(result)) {
                    return AjaxResult.error("银行卡校验接口异常");
                }
                JSONObject jsonObject = JSONObject.parseObject(result);
                JSONObject respObject = jsonObject.getJSONObject("resp");
                String resCode = respObject.getString("code");
                String resError = respObject.getString("desc");
                if (!"0".equals(resCode)) {
                    if(StringUtils.isEmpty(examinerGrant.getIsForce()) || "0".equals(examinerGrant.getIsForce())) {
                        //银行卡校验不通过的时候，如果前台IsForce==0，则不允许提交，前台让用户做二次确认
                        return AjaxResult.error("银行卡校验失败，请确认输入卡号和开户行信息是否有误，如果确认信息正确，请点击确认按钮再次提交，并于报道当天带银行卡原件报道！");
                    }else {
                        //强制提交的情况下，记录一下该卡没有通过验证
                        examinerGrant.setBlankName("校验不通过");
                    }
                }else{
                    JSONObject bankObj = jsonObject.getJSONObject("data");
//                    JSONObject bankObj = obj.getJSONObject("belong");
                    String bankName = bankObj.getString("bank_name");
                    String bankType = bankObj.getString("card_type");
                    examinerGrant.setBlankName(bankName);
                    examinerGrant.setCardType(bankType);
                    if (!StringUtils.isEmpty(examPoint.getBankNameLimit())  && examPoint.getBankNameLimit().indexOf(bankName) < 0) {
                        return AjaxResult.error("该卡号所在银行不支持，请更换该考点所支持的卡号");
                    }else{
                        if (!StringUtils.isEmpty(examPoint.getBankTypeLimit())) {
                            String[] bankTypes = examPoint.getBankTypeLimit().split(",");
                            for (int ni = 0; ni < bankTypes.length; ni++) {
                                if (bankTypes[ni].indexOf(bankName) >= 0 && !bankTypes[ni].contains(bankName + "(" + bankType + ")")) {
                                    return AjaxResult.error("该卡号类型不支持，当前支持卡类型:" + examPoint.getBankTypeLimit());
                                }
                            }
                        }
                    }
                }
            }
        }
        if ("1".equals(examPoint.getIsIssuingBank())) {
            if (org.apache.commons.lang.StringUtils.isEmpty(examinerGrant.getDepositName())) {
                return AjaxResult.error("当前考点开户行不允许为空");
            }
        }
        GrExaminerBankcard bankCard = new GrExaminerBankcard();
        bankCard.setBankCard(examinerGrant.getBlankCark());
        bankCard.setExaminerId(examinerGrant.getExaminerId());
        List<GrExaminerBankcard> banklist = bankcardService.selectGrExaminerBankcardList(bankCard);
        int bankId = 0;
        // 判断卡号是否存在
        if (banklist.size() > 0) {
            GrExaminerBankcard grExaminerBankcard = banklist.get(0);
            grExaminerBankcard.setBankSubName(examinerGrant.getDepositName());
            grExaminerBankcard.setPhone(examinerGrant.getBlankPhone());
            if("Y".equals(examinerGrant.getIsForce())) {
                //如果是强制提交的，银行卡的可信，不通过
                grExaminerBankcard.setVerifyFlag(0);
            }else {
                grExaminerBankcard.setVerifyFlag(1);
            }
            grExaminerBankcard.setCardType(examinerGrant.getCardType());
            bankId = bankcardService.updateGrExaminerBankcard(grExaminerBankcard);

        } else {
            GrExaminerBankcard grExaminerBankcard = new GrExaminerBankcard();
            grExaminerBankcard.setBankCard(examinerGrant.getBlankCark());
            grExaminerBankcard.setBankName(examinerGrant.getBlankName());
            grExaminerBankcard.setBankSubName(examinerGrant.getDepositName());
            grExaminerBankcard.setExaminerId(examinerGrant.getExaminerId());
            grExaminerBankcard.setPhone(examinerGrant.getBlankPhone());
            if("Y".equals(examinerGrant.getIsForce())) {
                //如果是强制提交的，银行卡的可信，不通过
                grExaminerBankcard.setVerifyFlag(0);
            }else {
                grExaminerBankcard.setVerifyFlag(1);
            }
            grExaminerBankcard.setCardType(examinerGrant.getCardType());
            bankId = bankcardService.insertGrExaminerBankcard(grExaminerBankcard);// 保存银行卡信息

        }
        if(bankId<=0){
            throw new CustomException("银行卡信息保存失败",500);
        }
        return AjaxResult.success();
    }
    public AjaxResult checkExaminerLoginInfo(ExaminerLoginDto examinerLoginDto){
        String name = examinerLoginDto.getName();
        String phone = examinerLoginDto.getPhone();
        String idcard = examinerLoginDto.getIdcard();
        String smsCode = examinerLoginDto.getSmsCode();
        String wechatId = examinerLoginDto.getWechatId();
        Long grantId = examinerLoginDto.getGrantId();
        if(StringUtils.isAnyEmpty(name,phone,idcard,smsCode)){
            return AjaxResult.error("错误的登陆信息");
        }
        if(grantId==null){
            return AjaxResult.error("错误的项目信息");
        }
        String key = PHONE_CODE + phone;
        String val = "";
        val = (String)redisCache.getCacheObject(key);
        if(!smsCode.equals(val) && !"888888".equals(smsCode)){
            return  AjaxResult.error("错误的短信验证码");
        }
        redisCache.deleteObject(key);
        return AjaxResult.success();
    }

    /**
     * 查询科类大类下拉列表
     */
    @PostMapping("/gelectGrFamiliesList")
    public AjaxResult gelectGrFamiliesList(@RequestBody GrFamilies grFamilies)
    {
        Long grantId = grFamilies.getGrantId();
        GrGrant grant = grantService.selectGrGrantById(grantId);
        grFamilies.setGranttypeId(grant.getGranttypeId());
        List<GrFamilies> list = familiesService.selectGrFamiliesList(grFamilies);
        return AjaxResult.success(list);
    }
    /**
     * 根据页面传入的大类，查询小类的选择列表
     * @param grFamiliesExampointDto
     * @return
     */
    @ResponseBody
    @PostMapping("/getFamiliesSelectList")
    public AjaxResult getFamiliesSelectList(@RequestBody GrFamiliesExampointDto grFamiliesExampointDto){
//        if(grFamiliesExampointDto.getParentId()==null){
//            return AjaxResult.error("请先选择科类！");
//        }
        Long grantId = grFamiliesExampointDto.getGrantId();
        GrGrant grant = grantService.selectGrGrantById(grantId);
        grFamiliesExampointDto.setGranttypeId(String.valueOf(grant.getGranttypeId()));
        List<GrFamiliesExampointDto> familiesExampointDtoList = grFamiliesExampointService.getFamiliesSelectList(grFamiliesExampointDto);
        return AjaxResult.success(familiesExampointDtoList);
    }

    /**
     * 根据派出单位id获取派出单位名称
     * @param companyId
     * @return
     */
    @ResponseBody
    @PostMapping("getComanynameById")
    public AjaxResult getComanynameById(Long companyId){
        return AjaxResult.success(companyService.selectGrCompanyById(companyId));
    }

    /**
     * 根据选择的科类关联出考点选择列表
     * @param grFamiliesExampointDto
     * @return
     */
    @ResponseBody
    @PostMapping("getExamponitListByFamiliesId")
    public AjaxResult getExamponitListByFamiliesId(@RequestBody GrFamiliesExampointDto grFamiliesExampointDto){
        GrFamiliesExampoint familiesExampoint = new GrFamiliesExampoint();
        familiesExampoint.setGrantId(grFamiliesExampointDto.getGrantId());
        familiesExampoint.setFamiliesId(grFamiliesExampointDto.getFamiliesId());
        List<GrFamiliesExampoint> familiesExampointList = grFamiliesExampointService.queryGrfamiliesExampointList(familiesExampoint);
        List<Long> examPointIds = new ArrayList<>();
        familiesExampointList.stream().forEach(familiesExampointIns->{
            examPointIds.add(familiesExampointIns.getExamPointId());
        });
        List<GrExamPoint> examPointList = examPointService.selectGrExamPointByIds(examPointIds);
        return AjaxResult.success(examPointList);
    }
}
